package com.z.admin.controller;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.z.admin.dao.DanmuMapper;
import com.z.admin.dao.FilesMapper;
import com.z.admin.entity.Danmu;
import com.z.admin.entity.Files;
import com.z.admin.service.IFilesService;
import com.z.common.base.PageTableRequest;
import com.z.common.base.ResponseCode;
import com.z.common.base.Results;
import com.z.common.utils.KitFileUtil;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author z
 * @since 2022-03-13
 */
@Controller
@RequestMapping("/admin/files")
@Slf4j
public class FilesController {

    @Value("${user.dir}")
    private String path;
    @Resource
    private FilesMapper fileMapper;
    @Resource
    private DanmuMapper danmuMapper;
    @Autowired
    private IFilesService fileService;
    @GetMapping("toList")
    @ApiOperation("文件列表页面")
    public String toList() {
        return "admin/files/filesList";
    }

    @GetMapping("toUploadPage")
    @ApiOperation("文件上传页面")
    public String toUploadPage() {
        return "admin/files/filesUpload";
    }

    @GetMapping("download")
    @ApiOperation("获取文件接口")
    public HttpServletResponse download(HttpServletRequest request,HttpServletResponse response,Integer id) {
        //数据库视频信息
        Files video = fileMapper.selectById(id);
        response.reset();
        //获取从那个字节开始读取文件
        String rangeString = request.getHeader("Range");

        try {
            //获取响应的输出流
            OutputStream outputStream = response.getOutputStream();
            File file = new File(path + video.getUrl());
            if (file.exists()) {


                // 取得文件名。
                String filename = file.getName();
                // 取得文件的后缀名。
                String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();

                // 以流的形式下载文件。
                InputStream fis = new BufferedInputStream(new FileInputStream(file));
                byte[] buffer = new byte[fis.available()];
                fis.read(buffer);
                fis.close();
                // 清空response
                response.reset();
                // 设置response的Header
                response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
                response.addHeader("Content-Length", "" + file.length());
                OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
                response.setContentType("application/octet-stream");
                toClient.write(buffer);
                toClient.flush();
                toClient.close();
            } else {
                String message = "file:" + video.getName() + " not exists";
                //解决编码问题
                response.setHeader("Content-Type", "application/json");
                outputStream.write(message.getBytes(StandardCharsets.UTF_8));
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }
    @GetMapping("show")
    @ApiOperation("获取文件接口")
    public void getVideo(HttpServletRequest request,HttpServletResponse response,Integer id) {
        //数据库视频信息
        Files video = fileMapper.selectById(id);
        response.reset();
        //获取从那个字节开始读取文件
        String rangeString = request.getHeader("Range");

        try {
            //获取响应的输出流
            OutputStream outputStream = response.getOutputStream();
            File file = new File(path + video.getUrl());
            if (file.exists()) {
                RandomAccessFile targetFile = new RandomAccessFile(file, "r");
                long fileLength = targetFile.length();
                //播放
;                if (rangeString != null) {

                    long range = Long.valueOf(rangeString.substring(rangeString.indexOf("=") + 1, rangeString.indexOf("-")));
                    //设置内容类型
                    response.setHeader("Content-Type", "video/mp4");
                    //设置此次相应返回的数据长度
                    response.setHeader("Content-Length", String.valueOf(fileLength - range));
                    //设置此次相应返回的数据范围
                    response.setHeader("Content-Range", "bytes " + range + "-" + (fileLength - 1) + "/" + fileLength);
                    //返回码需要为206，而不是200
                    response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
                    //设定文件读取开始位置（以字节为单位）
                    targetFile.seek(range);
                } else {//下载

                    //设置响应头，把文件名字设置好
                    response.setHeader("Content-Disposition", "attachment; filename=" + video.getName());
                    //设置文件长度
                    response.setHeader("Content-Length", String.valueOf(fileLength));
                    //解决编码问题
                    response.setHeader("Content-Type", "application/octet-stream");
                }


                byte[] cache = new byte[1024 * 300];
                int flag;
                while ((flag = targetFile.read(cache)) != -1) {
                    outputStream.write(cache, 0, flag);
                }
            } else {
                String message = "file:" + video.getName() + " not exists";
                //解决编码问题
                response.setHeader("Content-Type", "application/json");
                outputStream.write(message.getBytes(StandardCharsets.UTF_8));
            }

            outputStream.flush();
            outputStream.close();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @PostMapping(value = "/uploadImg")
    @ApiOperation("文件上传接口")
    @ResponseBody
    public Object uploadImg(@RequestParam("layuiFile") MultipartFile[] layuiFile, HttpServletRequest request, HttpServletResponse response){
        log.info("进入wph的layui图片上传接口》》》》》》》》》》》》》》》");
        Map<String,Object> map=new HashMap<>();
        Map<String,Object> map2=new HashMap<>();
        KitFileUtil kitFileUtil=new KitFileUtil();
        map = kitFileUtil.upload(layuiFile, request, response);
        String error = map.get("error").toString();
        if("101".equals(error)){
            return Results.failure(ResponseCode.error.getCode(), (String)map.get("message"));
        }
        map2.put("error",0);
        String url[]=(String[])map.get("url");
        map2.put("url",url[0]);
        Files file = new Files();
        file.setName((String)map.get("fileName"));
        file.setUrl(url[0]);
        file.setCreateTime(new Date());
        file.setType("tp");
        fileMapper.insert(file);
        return Results.success(map2);
    }

    @PostMapping(value = "/uploadVideo")
    @ApiOperation("文件上传接口")
    @ResponseBody
    public Object uploadVideo(@RequestParam("layuiVideo") MultipartFile[] layuiFile, HttpServletRequest request, HttpServletResponse response){
        log.info("进入wph的layui视频上传接口》》》》》》》》》》》》》》》");
        Map<String,Object> map=new HashMap<>();
        Map<String,Object> map2=new HashMap<>();
        KitFileUtil kitFileUtil=new KitFileUtil();
        map = kitFileUtil.upload(layuiFile, request, response);
        String error = map.get("error").toString();
        if("101".equals(error)){
            map2.put("error",101);
            map2.put("message",map.get("message"));
            return map;
        }
        map2.put("error",0);
        String url[]=(String[])map.get("url");
        Files file = new Files();
        file.setName((String)map.get("fileName"));
        file.setUrl(url[0]);
        file.setCreateTime(new Date());
        file.setType("sp");
        fileMapper.insert(file);
        int id = file.getId();
        map2.put("url", "/admin/files/show?id="+id);

        return Results.success(map2);
    }
    //跳转预览页面
    @RequestMapping(value = "/goLook", method = RequestMethod.GET)
    public Object goLook(HttpServletRequest request, HttpSession session){
        log.info("课堂管理 》预览");

        ModelAndView mv = new ModelAndView();
        String classVideo = request.getParameter("classVideo");

        mv.addObject("kitG", classVideo);
        mv.setViewName("admin/files/yulan");
        return mv;
    }

    @GetMapping("listByMap")
    @ApiOperation("文件列表条件分页查询")
    @ResponseBody
    public Results listByMap(PageTableRequest page, HttpServletRequest request) {
        page.countOffset();

        Map<String, Object> map = new HashMap<>();
        String name = request.getParameter("name");
        if(!StringUtils.isEmpty(name))
            map.put("name_like_s", name);

        Results<Files> results = fileService.findPageByMap(map, page.getOffset(), page.getLimit());
        return results;
    }

    @ApiOperation("文件修改接口")
    @PostMapping("update")
    @ResponseBody
    public Results update(Files file){
        try{

            file.setUpdateTime(new Date());
            fileMapper.updateById(file);
        }catch (Exception e){
            e.printStackTrace();
            return Results.failure(ResponseCode.error.getCode(), e.getMessage());
        }
        return Results.success();
    }

    @ApiOperation("文件删除接口--多个")
    @PostMapping("delAll")
    @ResponseBody
    public Results delAll(String ids){
       return fileService.delAll(ids);
    }


    //跳转弹幕视频播放页面
    @RequestMapping(value = "/goDanmu", method = RequestMethod.GET)
    public Object goDanmu(Integer id){
        ModelAndView mv = new ModelAndView();
        Map<String, Object> map = new HashMap<>();
        map.put("videoUrl", "/admin/files/show?id=" + id);
        map.put("id", id);
        map.put("danmus", getDanmuList1(id));
        mv.addObject("post", map);
        mv.setViewName("admin/files/danmu");
        return mv;
    }

    private List<Danmu> getDanmuList1(int postId) {
        List<Danmu> danmuList = danmuMapper.selectList(new QueryWrapper<Danmu>().eq("post_id", postId));
        String str = "[";
        for(Danmu d : danmuList){
            str += d.string() + ",";
        }
        str = str.substring(0,str.length()-1) + "]";
        return danmuList;
    }

    /**
     * 根据视频ID查询动漫，根据时间升序
     *
     * @param postId 视频ID
     * @return
     */
    @GetMapping(value = "/getDanmuList", produces = {"application/json;charset=UTF-8"})
    @ResponseBody
    public Object getDanmuList(@RequestParam("postId") Long postId) {
        List<Danmu> danmuList = danmuMapper.selectList(new QueryWrapper<Danmu>().eq("post_id", postId));
        String str = "[";
        for(Danmu d : danmuList){
            str += d.toString() + ",";
        }
        str = str.substring(0,str.length()-1) + "]";
        return str;
    }
    /**
     * 发布弹幕
     *
     * @param postId    视频ID
     * @param  danmuJson 弹幕对象JSON字符串,如
     *                  { "text":"内容","color":"#ffffff","size":"1","position":"0","time":37}
     * @return 返回什么不重要
     */
    @PostMapping("/postDanmu")
    @ResponseBody
    public String postDanmu(@RequestParam("postId") Long postId,
                            @RequestParam("userId") Long userId,
                            @RequestParam("danmu") String danmuJson) {
        if (userId == null) {
            return "error, not login";
        }
        Danmu danmu = JSON.parseObject(danmuJson, Danmu.class);
        danmu.setPostId(postId);
        danmu.setUserId(userId);
        danmu.setCreateTime(new Date());
        // 没开启，使用默认的
/*        danmuService.insert(danmu);
        postService.updateDanmuSize(postId);*/
        danmuMapper.insert(danmu);
        return "success";
    }
}